
/***************************************************************************************
****************************************************************************************
* FILE		: mcu.c
* Description	: 
*			  
* Copyright (c) 2020 by Simlife. All Rights Reserved.
* 
* History:
* Version		Name		Date				Description
   0.1		Alen			2020/05/07		Initial Version
   
****************************************************************************************
****************************************************************************************/

#include "includes.h"

void fillBufferWithValue(U8 *source, U16 length, U8 value)
{
	while (length)
	{
		*source = value;
		source++;
		length--;
	}
}

void initRam(void)
{
	fillBufferWithValue((U8 *)(&stSystem), sizeof(stSystem), 0);
	fillBufferWithValue((U8 *)(&stTime), sizeof(stTime), 0);
	fillBufferWithValue((U8 *)(&stVibration), sizeof(stVibration), 0);
	fillBufferWithValue((U8 *)(&stSentFifo), sizeof(stSentFifo), 0);
	fillBufferWithValue((U8 *)(&stReceiveFifo), sizeof(stReceiveFifo), 0);
	fillBufferWithValue((U8 *)(&stBtInfo), sizeof(stBtInfo), 0);
}

void initBank(void)
{
	/***********bank_init**************/
	for (_mp0 = 0xff; _mp0 > 0x7f; _mp0--)
	{ //bank0
		_iar0 = 0;
	}
	_bp = 1; //bank1
	for (_mp1 = 0xff; _mp1 > 0x7f; _mp1--)
	{
		_iar1 = 0;
	}
	_mp1 = 0x00;
	_bp = 0x00;
}

void initCommon(void)
{
	_smod = B0000_0001; //fsys = fh = 12Mhz
	_ctrl = B0000_0000;
	_wdtc = B1010_1101;	 // 2^16/flsb about 2.0s   watchdog off
	_acerl = B0000_0000; //disable adc pin

	_slcdc0 = B0000_0000; //disable lcd
	_slcdc1 = B0000_0000;
	_slcdc2 = B0000_0000;
	_slcdc3 = B0000_0000;
	_slcdc4 = B0000_0000;

	_integ = B0000_0000; //clear INT0 INT1
	_intc0 = B0000_0000; //clear all
	_intc1 = B0000_0000; //clear all
	_intc2 = B0000_0000; //clear all
	_mfi0 = B0000_0000;	 //clear all
	_mfi1 = B0000_0000;	 //clear all
	_mfi2 = B0000_0000;	 //clear all

	_lvdc = B0000_0000; //disable low power check
	_cpc = B0000_1000;	//disable comparator
	_simc0 = B1110_0000;
	_simc1 = B0000_0000; //iic close
	_simc2 = B0000_0000; //spi close
	_tmpc = B0000_0000;	 //disable all timer clk input/output pin
	_tbc = B0000_0000;

	_sledc0 = B0000_0000; //pin current PA PB level 0
	_sledc1 = B0000_1111; //pin current PC level 3   PD level 0
	_ifs = B0000_0000;	  //pin change position

	_ucr1 = B0000_0000;
	_ucr2 = B0000_0000;
	_brg = B0000_0000;

	_pawu = B0000_0000;
	_pac = B0000_0000;
	_papu = B0000_0000;
	_pa = B0000_0000;

	_pbc = B0000_0000;
	_pbpu = B0000_0000;
	_pb = B0000_0000;

	_pcc = B0000_0000;
	_pcpu = B0000_0000;
	_pc = B0000_0000;

	_pdc = B0000_0000;
	_pdpu = B0000_0000;
	_pd = B0000_0000;
}

void initWatchdog(void)
{
	_wdtc = B1010_1101; // 2^16/flsb about 2.0s   watchdog off
}

void initTimer2(void)
{
	_tm2c0 = B0010_0000; //clk fh/16   timer2 off
	_tm2c1 = B1100_0001; //timer mode , compare A
	_tm2al = B1001_0110; //150     150*(4/3) us = 200us
	_tm2ah = B0000_0000;
	START_TIMER2();
}

void initAdc(void)
{
	_sadc1 = B0000_0101; // choose outs, adc clock fsys/32
	_sadc2 = B0000_0000; // vref = vdd
	_sadc0 = B0011_0001; //adrfs = 1; adcpin AN1
	_acerl = B0000_0010;
						 // START_ADC();
}

void initCloseAdc(void)
{
	_sadc1 = B0000_0101; // choose outs, adc clock fsys/32
	_sadc2 = B0000_0000; // vref = vdd
	_sadc0 = B0001_0000; //adrfs = 1; adc off
	CLEAN_ADC_PIN_CHOOSE();
	STOP_ADC();
}

void initInt0(void)
{
	_integ = B0000_0011; //INT0 up/down trigger
	STOP_INT0();		 // int0 off
}

void initUART(void)
{
	_usr = B0000_0000;
	_ucr1 = B1000_0000;
	_ucr2 = B1110_0100;
	// _brg = B0000_1100; // 12M/(16*(12+1))=57600
	_brg = B0100_1101; // 12M/(16*(77+1))=9600
	// _brg = B0000_0101; // 11.0592M/(16*(6+1))=115200
	// _brg = 0x11;	    // 11.0592M/(16*(17+1))=38400
	_ure = 1;
	STOP_UART();
}

void initMcu(void)
{
	initBank();
	initCommon();
	initWatchdog();
	initTimer2();
	initCloseAdc();
	initInt0();
	initUART();
	initAdc();
}

#ifdef timer2
void __attribute((interrupt(0x10))) isrTimer2(void);
void isrTimer2(void)
{
	_t2af = 0; //clear flag
	flag200us = TRUE;

	stTime.count10ms++;
	if (stTime.count10ms > 49)
	{
		stTime.count10ms = 0;
		flag10ms = TRUE;
		stTime.count250ms++;
		if (stTime.count250ms > 24)
		{
			stTime.count250ms = 0;
			flag250ms = TRUE;
			stTime.count500ms++;
			if (stTime.count500ms > 1)
			{
				stTime.count500ms = 0;
				flag500ms = TRUE;
			}
		}
	}
}
#endif

#if 1
#ifdef __V2__
#pragma vector isr_uart @0x2c
#else
void __attribute((interrupt(0x2c))) isr_uart(void);
#endif
void isr_uart()
{
	U8 receivedbyte;
	static U8 re_cnt;
	static U8 data_len;
	U8 resiger_usr;

	resiger_usr = _usr;
	if (resiger_usr & 0x04)
	{ //_rxif
		receivedbyte = _txr_rxr;
		switch (stBtInfo.state)
		{
		case START:
			re_cnt = 0;
			if (receivedbyte == 0xFC)
			{
				stReceiveFifo.receive_buff_arrary[stReceiveFifo.input].receive_data[re_cnt++] = receivedbyte;
				stBtInfo.state = DATA;
				stBtInfo.overtime = 20; ///200ms
				data_len = 6;
			}
			break;
		case DATA:
			if (data_len != 0)
			{
				stReceiveFifo.receive_buff_arrary[stReceiveFifo.input].receive_data[re_cnt++] = receivedbyte;
				data_len--;
			}
			else
			{
				if (receivedbyte == 0xCF)
				{
					stReceiveFifo.receive_buff_arrary[stReceiveFifo.input].receive_data[re_cnt++] = receivedbyte;
					stReceiveFifo.receive_buff_arrary[stReceiveFifo.input].receive_data_len = re_cnt;
					stReceiveFifo.input++;
					if (stReceiveFifo.input >= RECEIVE_BUFFER_MAX)
					{
						stReceiveFifo.input = 0;
					}
				}
				stBtInfo.state = START;
			}
			break;
		case END:
		default:
			stBtInfo.state = START;
			break;
		}
	}
}

#endif